<?php

namespace Frieza\Modules\Task\Controllers;

use App\Admin\Extensions\WorkContent;
use App\Http\Controllers\Controller;
use App\Models\BasicEventLatitude;
use App\Models\Consumer;
use App\Models\DbInstance;
use App\Models\Event;
use App\Models\EventLatitude;
use App\Models\EventProperty;
use App\Models\SubEvent;
use App\Pockets\GridDataModel as pGridDataModel;
use Doraemon\model\Event\SubEvent as mSubEvent;
use Doraemon\model\Event\SubEventProperty as mSubEventProperty;
use Doraemon\model\Position\PositionRules;
use Doraemon\model\Task\TaskBase as mTaskBase;
use Doraemon\model\Task\TaskGroup as mTaskGroup;
use Doraemon\service\position\AdmOperationModule;
use Doraemon\tools\Log;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Form;
use Encore\Admin\Widgets\Tab;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;

class IndexController extends Controller
{

    const PAGE_SIZE = 20;

    public function __construct()
    {
        parent::__construct();
        Admin::script('$(".pjax-container").attr("id","pjax-container");', true);
    }

    public function index(Request $request, Content $content, $channel)
    {
        if (is_null($request->input('group_status'))) {
            $request->merge([
                'group_status' => mTaskGroup::GROUP_STATUS_NORMAL
            ]);
        }
        $params = $request->all();
        $condition['group_status'] = $params['group_status'];
        if ($params['cycle']) {
            $condition['cycle'] = $params['cycle'];
        }
        if ($params['id']) {
            $condition = ['id' => $params['id']];
        }
        $condition['ORDER'] = ['sort' => 'ASC', 'id' => 'ASC'];
        $pageSize = $request->input("per_page", 10);
        $page = $request->input("page", 1);
        $condition['LIMIT'] = [
            ($page - 1) * $pageSize,
            $pageSize
        ];
        $condition['channel'] = $channel;
        $list = mTaskGroup::selectList($condition);
        $ids = array_column($list, 'id');
        $taskRules = AdmOperationModule::getPositionRulesById($ids, PositionRules::MODULE_TYPE_TASK_GROUP);
        foreach ($list as &$row) {
            $row['user_profile'] = $taskRules[$row['id']] ?? [];
        }
        unset($condition['ORDER']);
        unset($condition['LIMIT']);
        $count = mTaskGroup::selectCount($condition);
        $gridModel = new pGridDataModel($list, $count);

        $gridList = Admin::grid($gridModel,
            function (Grid $grid) use ($gridModel) {
                $grid->paginate($gridModel->getPerPage());
//                $grid->disablePagination();
                $grid->filter(function (Grid\Filter $filter) {
                    $filter->disableIdFilter();
                    $filter->column(1 / 2, function (Grid\Filter $filter) {
                        $filter->equal('id', '任务组ID');
                        $filter->equal('cycle', '任务周期')->select(mTaskGroup::$cycleType);
                    });
                    $filter->column(1 / 2, function (Grid\Filter $filter) {
                        $filter->equal('group_status', '状态')->select(mTaskGroup::$groupStatus);
                    });
                    $filter->expand();
                });
                $grid->disableExport();
                $grid->disableRowSelector();
                $grid->column("id", '任务组ID')->sort();
                $grid->column('pid', '依赖任务组');
                $grid->column('group_title', '任务组名称');
                $grid->column('group_desc', '任务组描述');
                $grid->column('cycle', '任务周期')->replace(mTaskGroup::$cycleType);
                $grid->column('time_type', '任务时间')->display(function () {
                    if ($this->time_type == mTaskGroup::TIME_TYPE_EXPIRES_TIME) {
                        return date('Y.m.d', $this->start_time) . '-' . date('Y.m.d', $this->end_time);
                    } else {
                        return mTaskGroup::$timeType[$this->time_type];
                    }
                });
                $grid->column('reward_type', '完成所有奖励')->display(function () {
                    $content = '<ul class="list-unstyled">';
                    $content .= "<li>奖励类型：" . mTaskBase::$taskReward[$this->reward_type] . "</li>";
                    $content .= "<li>奖励值：" . $this->reward_value . "</li></ul>";
                    return $content;
                });
                $grid->column('user_profile', '分群信息')->userProfile();
                $grid->column('group_status', '状态')->replace(mTaskGroup::$groupStatus);
                $grid->actions(function (Grid\Displayers\Actions $actions) {
                    $actions->prepend('<a href="/admin/task/index/' . $actions->row->id . '/list" class="grid-row-view">查看任务</a>');
                });
            });
        $tab = new Tab();
        foreach (mTaskGroup::$channel as $type => $channelDesc) {
            if ($type == $channel) {
                $tab->add($channelDesc, $gridList->render(), true);
            } else {
                $url = url('/admin/task/index/' . $type);
                $tab->addLink($channelDesc, $url);
            }
        }
        $beRelated = true;
        return $content
            ->row($tab)
            ->header('任务组列表')
            ->description(' ')
            ->breadcrumb(['text' => '任务组列表']);
    }

    protected function buildSelectOptions($nodes, $parentId = 0, $prefix = '', $space = '&nbsp;')
    {
        $prefix = $prefix ?: '┝' . $space;
        $options = [];
        foreach ($nodes as $id => $node) {
            if ($node['pid'] == $parentId) {
                $title = $prefix . $space . $node['group_desc'];
                $childrenPrefix = str_replace('┝', str_repeat($space, 6), $prefix) . '┝' . str_replace(['┝', $space], '', $prefix);
                $children = $this->buildSelectOptions($nodes, $id, $childrenPrefix);
                $options[$id] = $title;
                if ($children) {
                    $options += $children;
                }
            }
        }
        return $options;
    }

    protected function buildNestedArray($nodes = [], $parentId = 0)
    {
        $branch = [];
        foreach ($nodes as $id => $node) {
            if ($node['pid'] == $parentId) {
                $children = $this->buildNestedArray($nodes, $id);
                if ($children) {
                    $node['children'] = $children;
                }
                $branch[$id] = $node;
            }
        }
        return $branch;
    }


    public function create(Request $request, Content $content, $channel, $id = 0)
    {
        $groupList = mTaskGroup::selectList(['channel' => $channel]);
        $pids = array_column($groupList, 'pid');
        $pids = array_filter(array_unique($pids));
        $groupList = array_column($groupList, null, 'id');
        $info = ($id && isset($groupList[$id])) ? $groupList[$id] : [];
        $options = [];
        foreach ($groupList as $groupId => $row) {
            if ($id && in_array($id, $pids)) {
                break;
            } else if (!$row['pid'] && $id != $groupId) {
                $options[$groupId] = $row['group_desc'];
            }
        }

        $event_options = $event_ids = $fields = [];
        if ($info) {
            $userProfile = AdmOperationModule::getPositionRulesById($id, PositionRules::MODULE_TYPE_TASK_GROUP, true) ?: [];
            $info['user_profile'] = $userProfile;

            $info['events'] = Consumer::getTaskEvents($id);
            // 事件配置
            list($event_options, $event_ids, $fields) = Consumer::getTaskEventSetting($id);
        } else {
            $info['events'] = [];
        }
        $info['start_time'] = $info['start_time'] ? date('Y-m-d', $info['start_time']) : date('Y-m-d');
        $info['end_time'] = $info['end_time'] ? date('Y-m-d', $info['end_time']) : date('Y-m-d');
        $requestUlr = url()->previous();
        $info['request_url'] = $requestUlr;

        $form = new Form($info);
        $form->hidden('id', 'id');
        $form->select('channel', '渠道')->options(mTaskGroup::$channel)->default($channel)->readOnly();
        $form->text('group_title', '任务组名称');
        $form->text('group_desc', '任务组描述');
        if (isset($info['id'])) {
            $form->select('cycle', '任务周期')->options(
                mTaskGroup::$cycleType
            )->when(mTaskGroup::CYCLE_TYPE_WEEK, function (Form $form) {
                $form->number('cycle_start', '每周几开始')->help('1~7,即周一～周日');
            })->readonly();
        } else {
            $form->select('cycle', '任务周期')->options(
                mTaskGroup::$cycleType
            )->when(mTaskGroup::CYCLE_TYPE_WEEK, function (Form $form) {
                $form->number('cycle_start', '每周几开始')->default(1)->help('1~7,即周一～周日');
            })->default(mTaskGroup::CYCLE_TYPE_ONCE);
        }
        $form->radio('time_type', '任务时间')->options(mTaskGroup::$timeType)->default(mTaskGroup::TIME_TYPE_NEVER_EXPIRES)
            ->when(mTaskGroup::TIME_TYPE_EXPIRES_TIME, function (Form $form) {
                $form->dateRange('start_time', 'end_time', '任务时间')->default(date('Y-m-d'));
            });
        $form->select('pid', '依赖任务组')->options($options)->help('依赖只能选择一级。同时一级无法再设置依赖');
        $form->radio('reward_type', '所有任务完成奖励')->options(
            mTaskBase::$taskReward
        )->when(mTaskBase::TASK_REWARD_BRAND_SCORE, function (Form $form) {
            $form->text('reward_value.brand_score', '奖励值');
        })->when(mTaskBase::TASK_REWARD_POINT, function (Form $form) {
            $form->text('reward_value.point', '奖励值');
        })->default(mTaskBase::TASK_REWARD_EMPTY);

        $form->table('events', '订阅事件配置', function (\Encore\Admin\Form\NestedForm $nest) use ($event_options, $event_ids, $fields) {
            // 所有定义的事件
            $allEvents = Event::all()->pluck('name', 'id')->toArray();
            // 事件基础维度
            $latitude = BasicEventLatitude::all()->pluck('name', 'id')->toArray();
            $ids = array_keys($latitude);
            $sourceUrl = array_map(function ($v) {
                return route('consumer.api', ['basic_event_latitude_id' => $v]);
            }, $ids);
            $keyArr = array_combine($ids, array_map(function ($v) {
                return 'key' . $v;
            }, $ids));

            $sourceUrl[] = route('consumer.fields');
            $keyArr[] = 'user_subject';

            $nest->select('event_id', '事件名称')->options($allEvents)->loads($keyArr, $sourceUrl);
            foreach ($latitude as $id => $name) {
                $nest->multipleSelect($keyArr[$id], $name)->options($event_options[$event_ids[$nest->getKey()] ?? 0][$id] ?? []);
            }
            $nest->select('user_subject', '用户主体')->options($fields[$event_ids[$nest->getKey()] ?? 0]);
        });
        $form->userProfile('user_profile', '用户分群')
            ->options(\Doraemon\service\position\UserProfileModule::$other_position_rules)
            ->generate();
        $form->hidden('request_url', 'request_url');
        $form->action('/admin/task/index/save');
        return $content
            ->row($form)
            ->header('创建任务组')
            ->description(' ')
            ->breadcrumb([
                'text' => '任务组列表',
                'url' => url('/admin/task/index/' . $channel)
            ], ['text' => '创建任务组']);
    }

    public function save(Request $request)
    {
        try {
            $params = $request->all();

            $requestUrl = $request->post('request_url', '');
            $id = $params['id'];
            $timeType = $params['time_type'];
            $startTime = 0;
            $channel = $params['channel'];
            if ($timeType == mTaskGroup::TIME_TYPE_EXPIRES_TIME) {
                $startTime = strtotime($params['start_time']);
                $endTime = strtotime($params['end_time']);
                if (!$startTime || !$endTime || $endTime < $startTime) {
                    throw new \Exception('请正确设置任务的有效期');
                }
            } else {
                $startTime = 0;
                $endTime = strtotime(date('2038-01-01'));
            }
            $rewardType = $params['reward_type'];
            $rewardValue = '';
            switch ($rewardType) {
                case mTaskBase::TASK_REWARD_BRAND_SCORE;
                    $rewardValue = $params['reward_value']['brand_score'];
                    break;
                case mTaskBase::TASK_REWARD_POINT:
                    $rewardValue = $params['reward_value']['point'];
                    break;
            }
            $data = [
                'pid' => $params['pid'],
                'group_title' => $params['group_title'],
                'group_desc' => $params['group_desc'],
                'cycle' => $params['cycle'],
                'cycle_start' => isset($params['cycle_start']) ? $params['cycle_start'] : 1,
                'time_type' => $timeType,
                'start_time' => $startTime,
                'end_time' => $endTime,
                'channel' => $channel,
                'reward_type' => $rewardType,
                'reward_value' => $rewardValue,
            ];
            if ($data['cycle'] == mTaskGroup::CYCLE_TYPE_WEEK && $data['cycle_start'] > 7) {
                $data['cycle_start'] = 7;
            } else if (empty($data['cycle_start']) || $data['cycle_start'] <= 0) {
                $data['cycle_start'] = 1;
            }
            //分群信息
            $userProfile = $request->input('user_profile', []);

            // 订阅事件配置
            $consumer_info = Consumer::where(['task_type' => Consumer::TASK_DAILY])->first();
            if (!empty($params['events']) && empty($consumer_info)) {
                $error = new MessageBag([
                    'title' => '操作失败, 消费者未定义'
                ]);
                return back()->with(compact('error'));
            }

            $consumer = Consumer::where(['task_type' => Consumer::TASK_DAILY])->first()->toArray();
            $extra_params = [
                'add_username' => Admin::user()->username
            ];

            $sub_event_ids = [];
            if ($id) {
                $info = mTaskGroup::getInfoById($id);
                // 订阅事件更新处理
                $task_event = SubEvent::where(['other_id' => $id, 'data_status' => SubEvent::STATUS_ON])->first();
                if (!empty($task_event)) {
                    $sub_event_ids = SubEvent::query()->where(['other_id' => $id, 'data_status' => SubEvent::STATUS_ON])->get()->pluck('id')->toArray();
                }
                Consumer::eventConfigSave($consumer['id'], $params['events'], $sub_event_ids, $extra_params, $id);

                mTaskGroup::updateData($data, ['id' => $id]);
                if ($info && $info['cycle'] != mTaskGroup::CYCLE_TYPE_LIMIT_TIME) {
                    mTaskBase::updateData(['start_time' => $data['start_time'], 'end_time' => $data['end_time']], ['group_id' => $id]);
                }

            } else {
                $id = mTaskGroup::insertData($data);
                // 订阅事件创建处理
                Consumer::eventConfigSave($consumer['id'], $params['events'], $sub_event_ids, $extra_params, $id);
            }
            if ($id) {
                AdmOperationModule::addUserProfile($id, $userProfile, PositionRules::MODULE_TYPE_TASK_GROUP);
            }
            $success = new MessageBag([
                'title' => '提交成功'
            ]);
            if (!empty($requestUrl)) {
                return redirect($requestUrl);
            }
            Log::info('保存任务组：', ['admin_id' => Admin::user()->id, 'url' => url()->current(), 'request' => $request->all()]);
            return redirect(url('/admin/task/index/' . $channel))->with(compact('success'));
        } catch (\Exception $e) {
            $error = new MessageBag([
                'title' => '操作失败,信息:' . $e->getMessage()
            ]);
            return back()->with(compact('error'));
        }
    }

    public function del(Request $request, $channel, $id)
    {
        try {
            if (!$id) {
                throw new \Exception('不存在的id');
            }
            mTaskGroup::updateData(['group_status' => mTaskGroup::GROUP_STATUS_DEL], ['id' => $id]);
            mTaskGroup::updateData(['pid' => 0], ['pid' => $id]);
            $sub_event_ids = mSubEvent::select('id', ['other_id' => $id]);
            mSubEvent::update(['data_status' => SubEvent::STATUS_DELETE], ['id' => $sub_event_ids]);
            mSubEventProperty::update(['status' => SubEvent::STATUS_DELETE], ['sub_event_id' => $sub_event_ids]);
            $success = [
                'title' => '任务组 ID: ' . $id . ' 删除成功',
                'code' => 1,
            ];
            Log::info('删除任务组：', ['admin_id' => Admin::user()->id, 'url' => url()->current(), 'request' => $request->all()]);
        } catch (\Exception $e) {
            $success = [
                'title' => '删除失败',
                'code' => 0,
                'status' => false,
                'msg' => '错误信息#file:' . $e->getFile() . '#line:' . $e->getLine() . '#msg:' . $e->getMessage(),
            ];
        }
        return response()->json($success);
    }

    public function sortGroup(Request $request)
    {
        $sortInfo = $request->input('sort');
        foreach ($sortInfo as $id => $sort) {
            mTaskGroup::updateData(['sort' => $sort], ['id' => $id]);
        }
        Log::info('任务组排序：', ['admin_id' => Admin::user()->id, 'url' => url()->current(), 'request' => $request->all()]);
    }

    public function delTask(Request $request, $groupId, $id)
    {
        try {
            if (!$id) {
                throw new \Exception('不存在的id');
            }
            mTaskBase::updateData(['task_status' => mTaskBase::TASK_STATUS_DEL], ['id' => $id, 'group_id' => $groupId]);
            $success = [
                'title' => '任务 ID: ' . $id . ' 删除成功',
                'code' => 1,
            ];
            Log::info('删除任务：', ['admin_id' => Admin::user()->id, 'url' => url()->current(), 'request' => $request->all()]);
        } catch (\Exception $e) {
            $success = [
                'title' => '删除失败',
                'code' => 0,
                'status' => false,
                'msg' => '错误信息#file:' . $e->getFile() . '#line:' . $e->getLine() . '#msg:' . $e->getMessage(),
            ];
        }
        return response()->json($success);
    }

    public function taskList(Request $request, Content $content, $groupId)
    {
        Admin::script(self::realTaskScript());
        if (is_null($request->input('task_status'))) {
            $request->merge([
                'task_status' => mTaskBase::TASK_STATUS_NORMAL
            ]);
        }
        $params = $request->all();
        $condition['task_status'] = $params['task_status'];
        if ($params['id']) {
            $condition = ['id' => $params['id']];
        }
        $groupInfo = $groupId ? mTaskGroup::getInfo(['id' => $groupId]) : [];
        if ($groupInfo) {
            $channel = $groupInfo['channel'];
            $header = $groupInfo['group_desc'];
            $condition['group_id'] = $groupId;
            $condition['ORDER'] = ['sort' => 'ASC', 'id' => 'ASC'];
            $pageSize = $request->input("per_page", 10);
            $page = $request->input("page", 1);
            $condition['LIMIT'] = [
                ($page - 1) * $pageSize,
                $pageSize
            ];

            $list = mTaskBase::selectList($condition);
            $relTaskIds = array_column($list, 'rel_task_id');
            $relTaskArr = $relTaskIds ? mTaskBase::selectList(['id' => $relTaskIds], ['id', 'task_title', 'group_id']) : [];
            $relGroupIds = !empty($relTaskArr) ? array_column($relTaskArr, 'group_id') : [];
            $relGroupArr = $relGroupIds ? mTaskGroup::selectList(['id' => $relGroupIds], ['id', 'group_desc', 'group_title']) : [];
            $relGroupList = $relGroupArr ? array_column($relGroupArr, null, 'id') : [];
            $relTaskList = [];
            foreach ($relTaskArr as $row) {
                $relTaskList[$row['id']] = [
                    'task_id' => $row['id'],
                    'task_title' => $row['task_title'],
                    'group_id' => $row['group_id'],
                    'group_desc' => $relGroupList[$row['group_id']]['group_desc']
                ];
            }
            foreach ($list as &$row) {
                $relTaskInfo = isset($relTaskList[$row['rel_task_id']]) ? $relTaskList[$row['rel_task_id']] : [];
                $row['rel_task_info'] = $relTaskInfo;
            }

            unset($condition['ORDER']);
            unset($condition['LIMIT']);
            $count = mTaskBase::selectCount($condition);
            $gridModel = new pGridDataModel($list, $count, [
                'perPage' => $pageSize
            ]);
            $isSort = false;
            if ($page == 1 && $page * $pageSize >= $count) {
                $isSort = true;
            }
            $isBrand = mTaskGroup::CHANNEL_BRAND_SERVICE == $channel;
            $gridList = Admin::grid($gridModel,
                function (Grid $grid) use ($gridModel, $isSort, $isBrand) {
                    $grid->paginate($gridModel->getPerPage());
                    $grid->filter(function (Grid\Filter $filter) {
                        $filter->disableIdFilter();
                        $filter->column(1 / 2, function (Grid\Filter $filter) {
                            $filter->equal('id', '任务ID');
                        });
                        $filter->column(1 / 2, function (Grid\Filter $filter) {
                            $filter->equal('task_status', '状态')->select(mTaskBase::$taskStatus);
                        });
                        $filter->expand();
                    });
                    $grid->disableExport();
                    $grid->disableRowSelector();
                    if ($isSort) {
                        $grid->column('id', '任务ID')->sort();
                    } else {
                        $grid->column('id', '任务ID');
                    }
                    $grid->column("group_id", '任务组ID');
                    $grid->column('task_title', '任务名称');
                    if ($isBrand) $grid->column("task_name", '任务类型')->using(\Biz\service\brand\BrandHandleTask::TASK_TYPE_MAP);
                    $grid->column('operate_num', '动作次数');
                    $grid->column('reward_type', '单次动作')->display(function () {
                        $content = '<ul class="list-unstyled">';
                        $content .= "<li>奖励类型：" . mTaskBase::$taskReward[$this->reward_type] . "</li>";
                        $content .= "<li>奖励值：" . $this->reward_value . "</li></ul>";
                        return $content;
                    });
                    $grid->column('finished_reward_type', '所有动作完成')->display(function () {
                        $content = '<ul class="list-unstyled">';
                        $content .= "<li>奖励类型：" . mTaskBase::$taskReward[$this->finished_reward_type] . "</li>";
                        $content .= "<li>奖励值：" . ($this->finished_reward_value ? $this->finished_reward_value : '无') . "</li></ul>";
                        return $content;
                    });
                    $grid->column('task_status', '状态')->replace(mTaskBase::$taskStatus);
                    $grid->column('rel_task_info', '关联任务')->display(function () {
                        $html = '';
                        if ($this->rel_task_id) {
                            $html .= '<p>分组ID：' . $this->rel_task_info['group_id'] . '(' . $this->rel_task_info['group_desc'] . ')</p>';
                            $html .= '<p>任务ID：' . $this->rel_task_info['task_id'] . '(' . $this->rel_task_info['task_title'] . ')</p>';
                        }
                        if ($this->berelated) {
                            $html .= '<p>已被关联</p>';
                        } else {
                            $html .= '<p><a href="javascript:;" class=" realTask" data-type=""   data-id="' . $this->id . '">关联任务</a>' . '</p>';
                        }
                        return $html;
                    });
                });
            $content->row($gridList);
            return $content
                ->header($header)
                ->description(' ')
                ->breadcrumb([
                    'text' => '任务组列表',
                    'url' => url('/admin/task/index/' . $channel)
                ], ['text' => '任务列表']);
        } else {
            return $content->row('不存在的任务组')
                ->header('任务列表');
        }
    }

    public function createTask(Request $request, Content $content, $groupId, $id = 0)
    {
        $groupInfo = $groupId ? mTaskGroup::getInfo(['id' => $groupId]) : [];
        if ($groupInfo) {
            $channel = $groupInfo['channel'];
            $header = $groupInfo['group_desc'];
            $info = $id ? mTaskBase::getInfo(['id' => $id]) : [];
            $relGroupOption = [];
            $relTaskOption = [];
            $realGroupList = mTaskGroup::selectList(['group_status[!]' => mTaskGroup::STATUS_DELETE, 'channel' => $channel], ['id', 'group_title', 'group_desc']);
            foreach ($realGroupList as $row) {
                $relGroupOption[$row['id']] = $row['group_title'] . '->' . $row['group_desc'];
            }
            if ($info) {
                unset($relGroupOption[$info['group_id']]);//不能关联当前分组的任务
                $rewardValue = $info['reward_value'];
                $info['reward_value'] = ['brand_score' => '', 'point' => ''];
                switch ($info['reward_type']) {
                    case mTaskBase::TASK_REWARD_BRAND_SCORE:
                        $info['reward_value']['brand_score'] = $rewardValue;
                        break;
                    case mTaskBase::TASK_REWARD_POINT:
                        $info['reward_value']['point'] = $rewardValue;
                        break;
                    case mTaskBase::TASK_REWARD_LEVEL:
                        $info['reward_value']['level'] = $rewardValue;
                        break;
                }
                $finishedRewardValue = $info['finished_reward_value'];
                $info['finished_reward_value'] = ['brand_score' => '', 'point' => ''];
                switch ($info['finished_reward_type']) {
                    case mTaskBase::TASK_REWARD_BRAND_SCORE:
                        $info['finished_reward_value']['brand_score'] = $finishedRewardValue;
                        break;
                    case mTaskBase::TASK_REWARD_POINT:
                        $info['finished_reward_value']['point'] = $finishedRewardValue;
                        break;
                    case mTaskBase::TASK_REWARD_LEVEL:
                        $info['finished_reward_value']['level'] = $finishedRewardValue;
                        break;
                }
                $info['link'] = [
                    'link_type' => $info['link_type'],
                    'link_params' => $info['link_params']
                ];
                $realTaskId = $info['rel_task_id'];
                if ($realTaskId) {
                    $info['rel_group_id'] = mTaskBase::getInfo(['id' => $realTaskId], 'group_id');
                }
                $relGroupId = isset($info['rel_group_id']) ? $info['rel_group_id'] : 0;
                $realTaskList = $relGroupId ? mTaskBase::selectList(['group_id' => $relGroupId, 'task_status[!]' => mTaskBase::TASK_STATUS_DEL, 'rel_task_id' => 0], ['id', 'task_title']) : [];
                foreach ($realTaskList as $row) {
                    $relTaskOption[$row['id']] = $row['task_title'];
                }
                if (isset($relTaskOption[$info['id']])) {
                    unset($relTaskOption[$info['id']]);
                }
            } else {
                $relGroupId = !empty($realGroupList) ? $realGroupList[0]['id'] : 0;
                $realTaskList = $relGroupId ? mTaskBase::selectList(['group_id' => $relGroupId, 'task_status[!]' => mTaskBase::TASK_STATUS_DEL, 'rel_task_id' => 0], ['id', 'task_title']) : [];
                foreach ($realTaskList as $row) {
                    $relTaskOption[$row['id']] = $row['task_title'];
                }
            }
            $info['start_time'] = date('Y-m-d H:i:s', $info['start_time']);
            $info['end_time'] = date('Y-m-d H:i:s', $info['end_time']);
            $info = array_merge($info, [
                'group_id' => $groupId,
                'group_cycle' => $groupInfo['cycle'],
                'group_title' => $groupInfo['group_title'],
                'group_desc' => $groupInfo['group_desc'],
                'group_start_time' => date('Y-m-d H:i:s', $groupInfo['start_time']),
                'group_end_time' => date('Y-m-d H:i:s', $groupInfo['end_time']),
            ]);
            $form = new Form($info);
            $form->hidden('group_id', '任务组id');
            $form->hidden('id', '任务id');
            $form->text('group_title', '任务组')->readonly();
            if ($channel == mTaskGroup::CHANNEL_BRAND_SERVICE) $form->select('task_name', '任务类型')->options(\Biz\service\brand\BrandHandleTask::TASK_TYPE_MAP);
            $form->text('task_title', '任务标题')->required();
            $form->text('task_sub_title', '任务副标题');
            $form->textarea('task_intro', '任务描述');
            if ($info['group_cycle'] == mTaskGroup::CYCLE_TYPE_LIMIT_TIME) {
                $form->dateTimeRange('group_start_time', 'group_end_time', '任务组时间')->readonly();
                $form->dateTimeRange('start_time', 'end_time', '任务时间')->required();
            }
            //$form->select('','事件')->options([1=>'点赞',2=>'分享商品',3=>'评论']);
            $form->number('operate_num', '动作次数')->default(1);
            $form->radio('reward_type', '单次动作')->options(
                mTaskBase::$taskReward
            )->when(mTaskBase::TASK_REWARD_BRAND_SCORE, function (Form $form) {
                $form->text('reward_value.brand_score', '奖励值');
            })->when(mTaskBase::TASK_REWARD_POINT, function (Form $form) {
                $form->text('reward_value.point', '奖励值');
            })->when(mTaskBase::TASK_REWARD_LEVEL, function (Form $form) {
                $form->text('reward_value.level', '成长值');
            })->default(mTaskBase::TASK_REWARD_EMPTY);

            $form->radio('finished_reward_type', '所有动作完成')->options(
                mTaskBase::$taskReward
            )->when(mTaskBase::TASK_REWARD_BRAND_SCORE, function (Form $form) {
                $form->text('finished_reward_value.brand_score', '奖励值');
            })->when(mTaskBase::TASK_REWARD_POINT, function (Form $form) {
                $form->text('finished_reward_value.point', '奖励值');
            })->when(mTaskBase::TASK_REWARD_LEVEL, function (Form $form) {
                $form->text('finished_reward_value.level', '成长值');
            })->default(mTaskBase::TASK_REWARD_EMPTY);

            $form->number('sort', '排序')->help('正序，非必填，不需要则缺省。如需，则保证同任务组下所有任务排序大于0。');

            $form->fieldset('任务跳转链接', function (Form $form) {
                $form->linkSelect('link', '任务跳转链接');
            });
            if (!$info['berelated']) {
                $form->fieldset('关联任务', function (Form $form) use ($relGroupOption, $relTaskOption, $header) {
                    $form->divider('当前分组：' . $header);
                    $form->select('rel_group_id', '选择任务组')->options($relGroupOption)->load('rel_task_id', url('/admin/task/getGroupTasks'));
                    $form->select('rel_task_id', '动作')->options($relTaskOption)->help($this->getRelHelp());
                });
            }

            $form->fieldset('添加操作', function (Form $form) {
                $form->select('action_type', '操作类型')->options(mTaskBase::$actionType)->default(0);
                $form->text('action_btn', '按钮名称');
            });

            $form->action('/admin/task/index/saveTask');
            return $content
                ->row($form)
                ->header($header)
                ->description(' ')
                ->breadcrumb([
                    'text' => '任务列表',
                    'url' => url('/admin/task/index/' . $groupId . '/list')
                ], ['text' => '编辑任务']);
        } else {
            return $content->row('请选择一个任务组')->header('创建任务');
        }
    }


    public function saveTask(Request $request)
    {
        try {
            $params = $request->all();
            $linkParams = $request->input("link_params", "");
            $linkType = $request->input('link_type', '');
            $actionType = $request->input("action_type", 0);
            $actionBtn = $request->input('action_btn', '');
            //$actionBtn = $actionType > 0 ? $actionBtn : '';
            $groupId = $params['group_id'];
            $groupInfo = $groupId ? mTaskGroup::getInfo(['id' => $groupId]) : [];
            $realTaskId = $request->input('rel_task_id', 0);
            if (!$groupInfo) {
                throw new \Exception('任务组参数错误');
            }
            $startTime = $request->input("start_time", '');
            $endTime = $request->input("end_time", '');
            $startTime = $startTime ? strtotime($startTime) : 0;
            $endTime = $endTime ? strtotime($endTime) : 0;
            if ($groupInfo['cycle'] == mTaskGroup::CYCLE_TYPE_LIMIT_TIME) {
                if (!$startTime || !$endTime || $endTime < $startTime) {
                    throw new \Exception('请正确填写时间区间');
                }
                if ($groupInfo['start_time'] > $startTime || $endTime > $groupInfo['end_time']) {
                    throw new \Exception('任务的时间必须在任务组时间范围内');
                }
            } else {
                $startTime = $groupInfo['start_time'];
                $endTime = $groupInfo['end_time'];
            }
            $id = $params['id'];
            $rewardType = $params['reward_type'];
            $rewardValue = '';
            switch ($rewardType) {
                case mTaskBase::TASK_REWARD_BRAND_SCORE;
                    $rewardValue = $params['reward_value']['brand_score'];
                    break;
                case mTaskBase::TASK_REWARD_POINT:
                    $rewardValue = $params['reward_value']['point'];
                    break;
                case mTaskBase::TASK_REWARD_LEVEL:
                    $rewardValue = $params['reward_value']['level'];
                    break;
            }
            $finishedRewardType = $params['finished_reward_type'];
            $finishedRewardValue = '';
            switch ($finishedRewardType) {
                case mTaskBase::TASK_REWARD_BRAND_SCORE;
                    $finishedRewardValue = $params['finished_reward_value']['brand_score'];
                    break;
                case mTaskBase::TASK_REWARD_POINT:
                    $finishedRewardValue = $params['finished_reward_value']['point'];
                    break;
                case mTaskBase::TASK_REWARD_LEVEL:
                    $finishedRewardValue = $params['finished_reward_value']['level'];
                    break;
            }

            $taskName = $params['task_name'] ?? '';
            $task_sub_title = $params['task_sub_title'] ?? '';
            if ($groupInfo['channel'] == mTaskGroup::CHANNEL_BRAND_SERVICE && !empty($taskName)) {
                list($task_sub_title, $linkType, $linkParams)  = \Biz\service\brand\BrandHandleTask::admParseTaskType($taskName);
            }

            $data = [
                'group_id' => $groupId,
                'task_name' => $taskName,
                'task_title' => $params['task_title'],
                'task_sub_title' => $task_sub_title,
                'task_intro' => $params['task_intro'],
                'operate_num' => $params['operate_num'] ? $params['operate_num'] : 1,
                'reward_type' => $rewardType,
                'reward_value' => $rewardValue,
                'finished_reward_type' => $finishedRewardType,
                'finished_reward_value' => $finishedRewardValue,
                'link_type' => $linkType,
                'link_params' => $linkParams ? json_encode($linkParams, JSON_UNESCAPED_UNICODE) : '',
                'action_type' => $actionType,
                'action_btn' => $actionBtn,
                'rel_task_id' => $realTaskId,
                'start_time' => $startTime,
                'end_time' => $endTime,
                'sort' => (isset($params['sort']) && $params['sort'] > 0) ? $params['sort'] : 0,
            ];
            if ($id) {
                $result = mTaskBase::updateData($data, ['id' => $id]);
            } else {
                $result = mTaskBase::insertData($data);
            }
            self::beRelateTask($realTaskId);
            $success = new MessageBag([
                'title' => '提交成功'
            ]);
            Log::info('保存任务：', ['admin_id' => Admin::user()->id, 'url' => url()->current(), 'request' => $request->all()]);
            return redirect(url('/admin/task/index/' . $groupId . '/list'))->with(compact('success'));
        } catch (\Exception $e) {
            $error = new MessageBag([
                'title' => '操作失败,信息:' . $e->getMessage()
            ]);
            return back()->with(compact('error'));
        }
    }

    public function sortTask(Request $request, $groupId)
    {
        $taskIds = mTaskBase::getTaskIdsByGroupId($groupId);
        $count = count($taskIds);
        $sortInfo = $request->input('sort');
        if (count($sortInfo) != $count) {
            return response()->json([
                'status' => false,
                'message' => "排序失败",
            ]);
        }
        foreach ($sortInfo as $id => $sort) {
            mTaskBase::updateData(['sort' => ($sort + 1)], ['id' => $id]);
        }
        Log::info('任务排序：', ['admin_id' => Admin::user()->id, 'url' => url()->current(), 'request' => $request->all()]);
        return response()->json([
            'status' => true,
            'message' => "排序成功",
        ]);
    }

    private static function beRelateTask($realTaskId)
    {
        $relCount = mTaskBase::selectCount(['rel_task_id' => $realTaskId]);
        if (!empty($relCount) && $relCount) {
            mTaskBase::updateData(['berelated' => 1], ['id' => $realTaskId]);
        } else {
            mTaskBase::updateData(['berelated' => 0], ['id' => $realTaskId]);
        }
    }

    public function realTask(Request $request, WorkContent $content, $id)
    {
        $code = $request->input('code', 0);
        if ($code == 1) {
            $script = <<<SCRIPT
            setTimeout(function () {
                        parent.window.location.reload();
                    }, 1000);
SCRIPT;
            Admin::script($script);
        }
        $info = mTaskBase::getInfoById($id);
        if (empty($info)) {
            return $content
                ->header('不存在的任务')
                ->description();
        }
        $groupInfo = mTaskGroup::getInfoById($info['group_id']);
        $realTaskId = $info['rel_task_id'];
        if ($realTaskId) {
            $info['rel_group_id'] = mTaskBase::getInfo(['id' => $realTaskId], 'group_id');
        }
        $relGroupOption = [];
        $relTaskOption = [];
        $realGroupList = mTaskGroup::selectList(['group_status[!]' => mTaskGroup::STATUS_DELETE, 'channel' => $groupInfo['channel']], ['id', 'group_title', 'group_desc']);
        foreach ($realGroupList as $row) {
            $relGroupOption[$row['id']] = $row['group_title'] . '->' . $row['group_desc'];
        }
        unset($relGroupOption[$info['group_id']]);//不能关联当前分组的任务
        $relGroupId = isset($info['rel_group_id']) ? $info['rel_group_id'] : 0;
        $realTaskList = $relGroupId ? mTaskBase::selectList(['group_id' => $relGroupId, 'task_status[!]' => mTaskBase::TASK_STATUS_DEL, 'rel_task_id' => 0], ['id', 'task_title']) : [];
        foreach ($realTaskList as $row) {
            $relTaskOption[$row['id']] = $row['task_title'];
        }
        if (isset($relTaskOption[$info['id']])) {
            unset($relTaskOption[$info['id']]);
        }

        $form = new Form($info);

        $form->text('id', '任务ID')->readonly();
        $form->text('task_title', '任务名称')->readonly();
        $form->select('rel_group_id', '选择任务组')->options($relGroupOption)->load('rel_task_id', url('/admin/task/getGroupTasks'));
        $form->select('rel_task_id', '动作')->options($relTaskOption)->help($this->getRelHelp());

        $form->action('/admin/task/postRelTask');
        $desc = '';
        $content->row($form);
        return $content
            ->header('关联任务')
            ->description($desc);
    }

    public function postRelTask(Request $request)
    {
        try {
            $id = $request->input('id', 0);
            $realTaskId = $request->input('rel_task_id', 0);
            $info = $id ? mTaskBase::getInfoById($id) : [];
            if (empty($id) || empty($info)) {
                throw new \Exception('不存在的任务');
            }
            $realTaskInfo = mTaskBase::getInfoById($realTaskId);
            if (empty($realTaskId) || empty($realTaskInfo)) {
                throw new \Exception('不存在的关联任务');
            }
            $result = mTaskBase::updateData(['rel_task_id' => $realTaskId], ['id' => $id]);
            self::beRelateTask($realTaskId);
            $success = new MessageBag([
                'title' => '添加成功',
            ]);
            Log::info('关联任务：', ['admin_id' => Admin::user()->id, 'url' => url()->current(), 'request' => $request->all()]);
            return redirect('/admin/task/relTask/' . $id . '?code=1')->with(compact('success'));
        } catch (\Exception $e) {
            $error = new MessageBag([
                'title' => '关联任务失败,' . $e->getMessage()
            ]);
            return back()->with(compact('error'));
        }
    }

    public function getGroupTasks(Request $request)
    {
        $id = $request->input('q', 0);
        $taskList = $id > 0 ? mTaskBase::selectList(['group_id' => $id, 'task_status[!]' => mTaskBase::TASK_STATUS_DEL, 'rel_task_id' => 0]) : [];
        $result = array_map(function ($task) {
            return [
                "id" => $task["id"],
                "text" => $task["task_title"]
            ];
        }, $taskList);
        return response()->json($result);
    }

    private function getRelHelp()
    {
        $help = [
            '关联之后，同时关联完成状态。',
            '&nbsp;&nbsp;&nbsp;&nbsp;只奖励用户当前操作的任务。',
            '&nbsp;&nbsp;&nbsp;&nbsp;关联后，当前任务不能再被关联。'
        ];
        return "<span style='color: red'>" . implode('<br/>', $help) . "</span>";
    }

    private function realTaskScript()
    {
        return <<<SCRIPT
        $('.realTask').unbind('click').click(function() {
            var id = $(this).data('id');
            layer.open({
                type: 2,
                title: '关联任务',
                shadeClose: true,
                shade: 0,
                maxmin: true,
                area: ['700px', '600px'],
                content: '/admin/task/relTask/'+id,
            });
		});
SCRIPT;
    }

    public function api($basic_event_latitude_id, Request $request)
    {
        $event_id = $request->input('q');
        $event_latitude = EventLatitude::where([
            'event_id' => $event_id,
            'basic_event_latitude_id' => $basic_event_latitude_id
        ])->get()->toArray();

        $event_latitude_ids = empty($event_latitude) ? [] : array_column($event_latitude, 'id');
        $event = empty($event_latitude_ids) ? [] : EventProperty::where(['event_id' => $event_id])->whereIn('event_latitude_id', $event_latitude_ids)->get()->toArray();

        $options = [];
        foreach ($event as $v) {
            $options[] = [
                'id' => $v['id'],
                'text' => $v['name'],
            ];
        }

        return response()->json($options);
    }

    public function fields(Request $request)
    {
        $id = $request->input('q');
        $event = Event::find($id);
        $column = DbInstance::getTableColumns($event['db_instance_id'], $event['database'], $event['tables'][0]);
        $options = ["" => ""] + $column[0]['options'];
        return response()->json($options);
    }
}
